package m;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.URL;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;

import m.framework.exception.SystemException;
import m.framework.utils.FileUtil;
import m.framework.utils.Os;
import m.framework.utils.StrBuilder;
import m.framework.utils.StringUtil;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.support.PropertiesLoaderUtils;

/**
 * 配置文件查找工具类
 * 
 * @author ming
 * @date 2014年2月18日上午10:07:27
 */
public class Config {
	private static Logger log = LoggerFactory.getLogger(Config.class);

	// 运行环境相关配置
	public static final String SYSTEM_CONFIG = "systemConfig.properties";
	// spring配置文件路径
	public static final String SPRING_ROOT = "/spring";
	// 模板配置文件
	public static final String TEMPLATE_CONFIG = "/velocity.properties";
	// 线程池配置文件
	public static final String THREAD_POOL = "config/threadInfo.properties";
	// 模板文件所在目录
	public static final String TEMPLATE_PATH = "/template";
	// 系统包前缀
	public static final String PACKAGE_ROOT = "m";
	// 表名前缀
	public static final String TABLE_PRE = "mm_";
	// baseInfo文件路径
	public static final String BASE_INFO_PATH = "config/baseInfo.properties";
	private static Properties systemConfig;
	// class所在目录
	private static String CLASS_PATH = null;
	private static String webRoot = null;
	// 项目部署实际路径
	private static String webapp = null;
	// 配置文件缓存,如果修改配置文件需手动调用Config.relaod()否则不会生效
	private static Map<String, Properties> configMap = new ConcurrentHashMap<String, Properties>();
	// 操作系统字符集
	public static String OS_CHARSET_NAME = System.getProperty("sun.jnu.encoding");

	public static void reload() {
		configMap = new ConcurrentHashMap<String, Properties>();
	}

	public static String getClassPath() {
		if (CLASS_PATH == null) {
			String className = Config.class.getSimpleName() + ".class";
			String fileName = Config.class.getResource(className).getFile();
			String dir = FileUtil.getDir(fileName);
			CLASS_PATH = FileUtil.parent(dir);
		}
		return CLASS_PATH;
	}

	/**
	 * 通过classpath查找文件
	 * 
	 * @param path 相对于classpath的路径
	 * */
	public static Properties readProperties(String path) {
		try {
			if (StringUtil.isEmpty(path)) {
				throw new SystemException("配置文件参数不能为空");
			}
			
			Properties pro = configMap.get(path);
			if (pro != null) {
				return pro;
			}
			
			URL d = Config.class.getResource("/" + path);
			if (d == null) {
				throw new SystemException("找不到资源文件:" + path);
			}
			Properties p = PropertiesLoaderUtils.loadAllProperties(path);

			if (p.isEmpty()) {
				throw new SystemException("配置文件" + path + "内容为空");
			}
			log.info("读取了资源文件:" + path + "\n" + p);
			
			configMap.put(path, p);
			return p;
		} catch (IOException e) {
			throw new SystemException("读取文件" + path + "失败", e);
		}
	}

	private static Properties systemConfig() {
		if (systemConfig == null) {
			systemConfig = readProperties(SYSTEM_CONFIG);
		}
		return systemConfig;
	}

	public static String webRoot() {
		if (webRoot == null) {
			return "";
		}
		return webRoot;
	}

	/** 获得spring配置文件 */
	public static String[] getSpringConfig() {
		String path = Config.class.getResource(SPRING_ROOT).getPath();
		List<File> file = FileUtil.getAllFile(path);
		String[] result = new String[file.size()];
		for (int i = 0; i < result.length; i++) {
			result[i] = Os.currrent().getSpringPath(file.get(i));
			log.info("找到配置文件:" + result[i]);
		}
		return result;
	}

	public static String getDevIp() {
		return systemConfig().getProperty("devIp");
	}

	public static String getBetaIp() {
		return systemConfig().getProperty("betaIp");
	}

	public static String getProdIp() {
		return systemConfig().getProperty("prodIp");
	}

	private static boolean init = false;

	// 通过httpservletrequest里的信息设置环境变量
	public static void initByRequest(String webRoot, String webapp) {
		if (init) {
			return;
		}
		Config.webRoot = webRoot;
		Config.webapp = webapp;
		init = true;
	}

	public static boolean isInit() {
		return init;
	}

	public static boolean isDevModal() {
		String dev = systemConfig().getProperty("devModal");
		if (StringUtil.isEmpty(dev)) {
			return false;
		}
		return Boolean.parseBoolean(dev);
	}

	public static String print() {
		StrBuilder sb = new StrBuilder();
		for (Method m : Config.class.getDeclaredMethods()) {
			// 只取参数为0的
			if (m.getParameterTypes().length != 0) {
				continue;
			}
			// public
			if (!Modifier.isPublic(m.getModifiers())) {
				continue;
			}
			// 静态的
			if (!Modifier.isStatic(m.getModifiers())) {
				continue;
			}
			// 跳过自己
			if ("print".equals(m.getName())) {
				continue;
			}
			try {
				sb.appendLine(m.getName(), m.invoke(Config.class), "=");
			} catch (Exception ex) {
				throw new SystemException("调用方法失败:" + m.getName(), ex);
			}
		}
		return sb.toString();
	}

	public static String getUploadRoot() {
		return systemConfig().getProperty("uploadRoot");
	}

	public static String webapp() {
		return webapp;
	}
}
